package com.ticket.web.controller.wx;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.ticket.common.constant.Constants;
import com.ticket.common.core.domain.AjaxResult;
import com.ticket.framework.web.service.SysLoginService;
import com.ticket.system.domain.vo.WxLoginBody;
import com.ticket.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 微信小程序用户接口
 *
 */
@RestController
@AllArgsConstructor
@Slf4j
@RequestMapping("/wx/user")
@Api(description = "微信登录管理")
public class WxMaUserController {
    private static final Logger logger = LoggerFactory.getLogger(WxMaUserController.class);
    private final WxMaService wxMaService;

    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 登陆接口
     */
    @ApiOperation("获取微信openid")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "登录code", dataType = "String", required = true,dataTypeClass = String.class),
            @ApiImplicitParam(name = "appid", value = "appid", dataType = "String", required = true,dataTypeClass = String.class)
    })
    @GetMapping("/login/forAllUser")
    public AjaxResult login(String appid, String code) {
        if (StringUtils.isBlank(code)) {
            return AjaxResult.error("empty jscode");
        }
        if (!wxMaService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }
        AjaxResult ajax = AjaxResult.success();
        WxMaJscode2SessionResult session = null;
        try {
            session = wxMaService.getUserService().getSessionInfo(code);
            if(null == session){
                return AjaxResult.error("获取微信会话失败！");
            }
            logger.info("login code:{} SessionKey:{} Openid:{}",code,session.getSessionKey(),session.getOpenid());
            String token = loginService.loginByOpenId(session.getOpenid());
            ajax.put(Constants.TOKEN, token);
        } catch (Exception e) {
            log.info("login error code:{} appid:{} msg:{}", code,appid,e.getMessage());
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
            ajax.put("session",session);
        }
        return ajax;
    }

    /**
     * <pre>
     * 获取用户信息接口
     * </pre>
     */
    @ApiOperation("获取用户信息接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "appId", value = "小程序appid", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "sessionKey", value = "小程序sessionKey", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "signature", value = "小程序signature", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "rawData", value = "小程序rawData", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "encryptedData", value = "小程序encryptedData", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "iv", value = "小程序iv", dataType = "String", dataTypeClass = String.class)
    })
    @GetMapping("/info/forAllUser")
    public AjaxResult info(String appid, String sessionKey,
                       String signature, String rawData, String encryptedData, String iv) {
        if (!wxMaService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }

        // 用户信息校验
        if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            WxMaConfigHolder.remove();//清理ThreadLocal
            return AjaxResult.error("user check failed");
        }

        // 解密用户信息
        WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
        WxMaConfigHolder.remove();//清理ThreadLocal
        return AjaxResult.success(userInfo);
    }

    /**
     * <pre>
     * 获取用户绑定手机号信息
     * </pre>
     */
    @ApiOperation("获取用户绑定手机号信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "appId", value = "小程序appid", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "code", value = "小程序code", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "openId", value = "小程序openId", dataType = "String", dataTypeClass = String.class)
    })
    @GetMapping("/phone/forAllUser")
    public AjaxResult phone(String appid, String code,String openId) {
        if (!wxMaService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }
        AjaxResult ajax = AjaxResult.success();
        WxMaPhoneNumberInfo phoneNoInfo = null;
        try {
//        // 用户信息校验
//        if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
//            WxMaConfigHolder.remove();//清理ThreadLocal
//            return AjaxResult.error("user check failed");
//        }

            // 解密
            phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(code);
            if(StringUtils.isEmpty(phoneNoInfo.getPhoneNumber())){
                return AjaxResult.error("获取微信手机号失败");
            }
            ajax.put("phoneNoInfo",phoneNoInfo);
            String token = loginService.loginByPhone(phoneNoInfo.getPhoneNumber(),openId);
            ajax.put(Constants.TOKEN, token);
        } catch (Exception e){
            log.info("根据手机号登录失败:{} {}", openId,phoneNoInfo);
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
        return ajax;
    }

    /**
     * 手机号openid自动登录方法
     *
     * @return 结果
     */
    @ApiOperation("自动登录")
    @ApiImplicitParam(name = "wxLoginBody", value = "微信登录对象", dataType = "WxLoginBody", dataTypeClass = WxLoginBody.class)
    @PostMapping("/loginAuto/forAllUser")
    public AjaxResult loginAuto(@RequestBody @Validated WxLoginBody wxLoginBody) {
        AjaxResult ajax = AjaxResult.success();
        String token = null;
        try {
            token = loginService.loginByOpenId(wxLoginBody.getOpenId());
        } catch(Exception e){
            log.info("自动登录失败 新增用户:{}",wxLoginBody);
            sysUserService.wxLogin(wxLoginBody);
            token = loginService.loginByOpenId(wxLoginBody.getOpenId());
        } finally {
            ajax.put(Constants.TOKEN, token);
        }
        return ajax;
    }
}
